package lines.gameengine.strategy;

import lines.gameengine.Ball;
import lines.gameengine.stub.StubField;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;

/**
 * @author vpotapenko
 */
public class DefaultBallStrategyTest {

    private static final int VALUE = 3;

    private StubField field;
    private DefaultBallStrategy strategy;

    @Before
    public void setUp() throws Exception {
        field = new StubField(9, 9);
        field.context.parameters.setLineSize(5);

        strategy = new DefaultBallStrategy(field, VALUE);
    }

    @Test public void shouldClearHorizontalLines() {
        field.getCell(0, 0).setBall(new Ball(strategy));
        field.getCell(1, 0).setBall(new Ball(strategy));
        field.getCell(2, 0).setBall(new Ball(strategy));
        field.getCell(3, 0).setBall(new Ball(strategy));
        field.getCell(4, 0).setBall(new Ball(strategy));

        assertThat(strategy.apply(field.getCell(2, 0).getPoint()), equalTo(true));

        assertThat(field.getCell(0, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(1, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(2, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(3, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 0).isEmpty(), equalTo(true));
    }

    @Test public void shouldClearVerticalLines() {
        field.getCell(0, 0).setBall(new Ball(strategy));
        field.getCell(0, 1).setBall(new Ball(strategy));
        field.getCell(0, 2).setBall(new Ball(strategy));
        field.getCell(0, 3).setBall(new Ball(strategy));
        field.getCell(0, 4).setBall(new Ball(strategy));

        assertThat(strategy.apply(field.getCell(0, 2).getPoint()), equalTo(true));

        assertThat(field.getCell(0, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(0, 1).isEmpty(), equalTo(true));
        assertThat(field.getCell(0, 2).isEmpty(), equalTo(true));
        assertThat(field.getCell(0, 3).isEmpty(), equalTo(true));
        assertThat(field.getCell(0, 4).isEmpty(), equalTo(true));
    }

    @Test public void shouldClearForwardDiagonalLines() {
        field.getCell(0, 0).setBall(new Ball(strategy));
        field.getCell(1, 1).setBall(new Ball(strategy));
        field.getCell(2, 2).setBall(new Ball(strategy));
        field.getCell(3, 3).setBall(new Ball(strategy));
        field.getCell(4, 4).setBall(new Ball(strategy));

        assertThat(strategy.apply(field.getCell(2, 2).getPoint()), equalTo(true));

        assertThat(field.getCell(0, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(1, 1).isEmpty(), equalTo(true));
        assertThat(field.getCell(2, 2).isEmpty(), equalTo(true));
        assertThat(field.getCell(3, 3).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 4).isEmpty(), equalTo(true));
    }

    @Test public void shouldClearBackwardDiagonalLines() {
        field.getCell(0, 4).setBall(new Ball(strategy));
        field.getCell(1, 3).setBall(new Ball(strategy));
        field.getCell(2, 2).setBall(new Ball(strategy));
        field.getCell(3, 1).setBall(new Ball(strategy));
        field.getCell(4, 0).setBall(new Ball(strategy));

        assertThat(strategy.apply(field.getCell(2, 2).getPoint()), equalTo(true));

        assertThat(field.getCell(0, 4).isEmpty(), equalTo(true));
        assertThat(field.getCell(1, 3).isEmpty(), equalTo(true));
        assertThat(field.getCell(2, 2).isEmpty(), equalTo(true));
        assertThat(field.getCell(3, 1).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 0).isEmpty(), equalTo(true));
    }

    @Test public void shouldClearBallsWithTwoTypesLines() {
        field.getCell(0, 0).setBall(new Ball(strategy));
        field.getCell(1, 0).setBall(new Ball(strategy));
        field.getCell(2, 0).setBall(new Ball(strategy));
        field.getCell(3, 0).setBall(new Ball(strategy));
        field.getCell(4, 0).setBall(new Ball(strategy));
        field.getCell(4, 1).setBall(new Ball(strategy));
        field.getCell(4, 2).setBall(new Ball(strategy));
        field.getCell(4, 3).setBall(new Ball(strategy));
        field.getCell(4, 4).setBall(new Ball(strategy));

        assertThat(strategy.apply(field.getCell(4, 0).getPoint()), equalTo(true));

        assertThat(field.getCell(0, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(1, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(2, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(3, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 0).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 1).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 2).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 3).isEmpty(), equalTo(true));
        assertThat(field.getCell(4, 4).isEmpty(), equalTo(true));
    }
}
